﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Aima.NET.Test.Core.Logic.FOL.Inference
{
    using System.Diagnostics;

    using Aima.Core.Logic.FOL.Inference;
    using Aima.Core.Logic.FOL.Inference.Trace;
    using Aima.Core.Logic.FOL.KB.Data;

    [TestClass]
    public class FOLTFMResolutionPerformance : CommonFOLInferenceProcedureTests 
    {

        //TODO: change to more standard performance test
        [TestMethod]
        [Ignore]
        public void TestFullFOLKBLovesAnimalQueryKillsJackTunaFalse() 
        {
            // This query will not return using TFM as keep expanding
            // clauses through resolution for this KB.
            var ip = new FOLTFMResolution(200 * 200);
            ip.Tracer = new RegressionFOLTFMResolutionTracer();
            this.TestFullFOLKBLovesAnimalQueryKillsJackTunaFalse(ip, true);
        }

        private class RegressionFOLTFMResolutionTracer : IFOLTFMResolutionTracer {
            private int outerCnt = 1;
            private int noPairsConsidered = 0;
            private int noPairsResolved = 0;
            private int maxClauseSizeSeen = 0;

            public void StepStartWhile(ISet<Clause> clauses, int totalNoClauses, int totalNoNewCandidateClauses) 
            {
                outerCnt = 1;

                
                Debug.WriteLine("");
                Debug.WriteLine("Total # clauses=" + totalNoClauses
                        + ", total # new candidate clauses="
                        + totalNoNewCandidateClauses);
            }

            public void StepOuterFor(Clause i) 
            {
                Debug.Write(" " + outerCnt);
                if (outerCnt % 50 == 0) {
                    Debug.WriteLine("");
                }
                outerCnt++;
            }

            public void StepInnerFor(Clause i, Clause j) {
                noPairsConsidered++;
            }

            public void StepResolved(Clause iFactor, Clause jFactor,
                    ISet<Clause> resolvents) {
                noPairsResolved++;

                Clause egLargestClause = null;
                foreach (Clause c in resolvents) 
                {
                    if (c.GetNumberLiterals() > maxClauseSizeSeen) 
                    {
                        egLargestClause = c;
                        maxClauseSizeSeen = c.GetNumberLiterals();
                    }
                }
                if (null != egLargestClause) {
                    Debug.WriteLine("");
                    Debug.WriteLine("E.g. largest clause so far="
                            + maxClauseSizeSeen + ", " + egLargestClause);
                    Debug.WriteLine("i=" + iFactor);
                    Debug.WriteLine("j=" + jFactor);
                }
            }

            public void StepFinished(ISet<Clause> clauses, IInferenceResult result) {
                Debug.WriteLine("Total # Pairs of Clauses Considered:"
                        + noPairsConsidered);
                Debug.WriteLine("Total # Pairs of Clauses Resolved  :"
                        + noPairsResolved);
                noPairsConsidered = 0;
                noPairsResolved = 0;
                maxClauseSizeSeen = 0;
            }
        }
    }
}
